package com.my.blog.service.impl;

import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.my.blog.constant.SystemConstants;
import com.my.blog.dao.RoleMapper;
import com.my.blog.dao.UserMapper;
import com.my.blog.dao.UserRoleMapper;
import com.my.blog.domain.ResponseResult;
import com.my.blog.domain.dto.AdminUserDto;
import com.my.blog.domain.dto.UserAddDto;
import com.my.blog.domain.entity.LoginUser;
import com.my.blog.domain.entity.Role;
import com.my.blog.domain.entity.User;
import com.my.blog.domain.entity.UserRole;
import com.my.blog.domain.vo.*;
import com.my.blog.enums.AppHttpCodeEnum;
import com.my.blog.exception.SystemException;
import com.my.blog.service.IAdminUserService;
import com.my.blog.utils.BeanCopyUtils;
import com.my.blog.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static net.sf.jsqlparser.util.validation.metadata.NamedObject.user;

@Service
public class AdminUserServiceImpl implements IAdminUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserRoleMapper userRoleMapper;


    @Override
    public ResponseResult getUserList(Integer pageNum, Integer pageSize, String userName, String phonenumber, String status) {
        // 构造查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(userName), User::getUserName, userName);
        queryWrapper.eq(StringUtils.isNotBlank(phonenumber), User::getPhonenumber, phonenumber);
        queryWrapper.eq(StringUtils.isNotBlank(status), User::getStatus, status);
        queryWrapper.orderByDesc(User::getCreateTime);

        // 创建分页参数对象
        Page<User> pageParam = new Page<>();
        pageParam.setSize(pageSize);
        pageParam.setCurrent(pageNum);

        // 执行分页查询
        userMapper.selectPage(pageParam, queryWrapper);

        // 调试用，确认分页数据
        System.out.println("当前页记录数：" + pageParam.getRecords().size());
        System.out.println("总记录数：" + pageParam.getTotal());
        System.out.println("总页数：" + pageParam.getPages());

        // 数据转换（实体类转VO）
        List<AdminUserVo> userVos = pageParam.getRecords().stream()
                .map(user -> {
                    AdminUserVo vo = new AdminUserVo();
                    BeanUtils.copyProperties(user, vo);
                    return vo;
                })
                .collect(Collectors.toList());

        // 构建分页返回对象
        PageVo pageVo = new PageVo(userVos, pageParam.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getListAllRole() {
        // 构造查询条件：状态正常（status=0）且未删除（delFlag=0）的角色
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getStatus, SystemConstants.STATUS_NORMAL);

        // 执行查询
        List<Role> roleList = roleMapper.selectList(queryWrapper);

        // 转换为VO对象
        List<AdminRoleVo> roleVoList = roleList.stream()
                .map(role -> {
                    AdminRoleVo vo = new AdminRoleVo();
                    BeanUtils.copyProperties(role, vo);
                    return vo;
                })
                .collect(Collectors.toList());

        // 返回结果
        return ResponseResult.okResult(roleVoList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult addUser(UserAddDto userAddDto) {
        //检查用户名是否为空
        if (userAddDto.getUserName().isEmpty()) {
            throw new SystemException(AppHttpCodeEnum.REQUIRE_USERNAME);
        }
        //检查用户名是否唯一
        if (checkUserNameExist(userAddDto.getUserName())) {
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
        //检查手机号是否唯一
        if (StringUtils.isNotBlank(userAddDto.getPhonenumber()) && checkPhonenumberExist(userAddDto.getPhonenumber())) {
            throw new SystemException(AppHttpCodeEnum.PHONENUMBER_EXIST);
        }
        //检查邮箱是否唯一
        if (StringUtils.isNotBlank(userAddDto.getEmail()) && checkEmailExist(userAddDto.getEmail())) {
            throw new SystemException(AppHttpCodeEnum.EMAIL_EXIST);
        }

        //密码加密
        User user = new User();
        BeanUtils.copyProperties(userAddDto, user);
        user.setPassword(passwordEncoder.encode(userAddDto.getPassword()));

        //插入用户数据
        userMapper.insert(user);

        //关联角色
        if (userAddDto.getRoleIds() != null && !userAddDto.getRoleIds().isEmpty()) {
            insertUserRoleRelations(user.getId(), userAddDto.getRoleIds());
        }

        return ResponseResult.okResult();

    }

    @Override
    public ResponseResult deleteUser(Long id) {

        //获取当前用户id
        Long currentUserId = SecurityUtils.getUserId();
        //检查是否删除当前用户
        if (id.equals(currentUserId)) {
            throw new SystemException(AppHttpCodeEnum.CANNOT_DELETE_CURRENT_USER);
        }

        userMapper.deleteById(id);

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getUserInfoById(Long id) {

        // 查询用户关联的角色ID列表
        List<String> roleIdList = roleMapper.selectRoleIdByUserId(id);

        // 构建角色查询条件（无过滤条件，查询所有角色）
        LambdaQueryWrapper<Role> roleQueryWrapper = new LambdaQueryWrapper<>();
        // 执行查询获取所有角色列表
        List<Role> roles = roleMapper.selectList(roleQueryWrapper);

        // 构建用户查询条件（根据用户ID精确查询）
        LambdaQueryWrapper<User> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.eq(User::getId, id);
        // 执行查询获取单个用户信息
        User user = userMapper.selectOne(userQueryWrapper);

        // 封装查询结果到VO对象（包含角色ID列表、所有角色、用户信息）
        AdminUserRoleVo adminUserRoleVo = new AdminUserRoleVo(roleIdList, roles, user);

        return ResponseResult.okResult(adminUserRoleVo);

    }

    @Override
    public ResponseResult updateUserInfo(AdminUserDto adminUserDto) {

        User user = userMapper.selectById(adminUserDto.getId());

        //更新用户基本信息
        BeanUtils.copyProperties(adminUserDto, user);
        user.setUpdateBy(SecurityUtils.getUserId()); // 设置更新人
        userMapper.updateById(user);

        //更新用户角色关联关系
        if (adminUserDto.getRoleIds() != null) {
            // 先删除原有关联关系
            LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserRole::getUserId, adminUserDto.getId());
            userRoleMapper.delete(queryWrapper);

            // 再插入新的关联关系
            List<Long> roleIdList = adminUserDto.getRoleIds().stream()
                    .map(Long::parseLong)
                    .collect(Collectors.toList());
            insertUserRoleRelations(adminUserDto.getId(), roleIdList);
        }

        return ResponseResult.okResult();
    }


    // 检查邮箱是否存在
    private boolean checkEmailExist(String email) {
        return userMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getEmail, email)) > 0;
    }

    // 检查手机号是否存在
    private boolean checkPhonenumberExist(String phonenumber) {
        return userMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getPhonenumber, phonenumber)) > 0;
    }

    // 检查用户名是否存在
    private boolean checkUserNameExist(String userName) {
        return userMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getUserName, userName)) > 0;
    }

    /**
     * 插入用户角色关联关系
     */
    private void insertUserRoleRelations(Long userId, List<Long> roleIds) {
        // 先校验角色是否存在
        LambdaQueryWrapper<Role> roleQueryWrapper = new LambdaQueryWrapper<>();
        roleQueryWrapper.in(Role::getId, roleIds);
        List<Role> roleList = roleMapper.selectList(roleQueryWrapper);

        // 只处理存在的角色
        roleIds.retainAll(roleList.stream().map(Role::getId).collect(java.util.stream.Collectors.toList()));

        // 插入用户角色关联
        roleIds.forEach(roleId -> {
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRoleMapper.insert(userRole);
        });
    }

}